/*
 * 文 件 名:  ExtractZipArchive.java
 * 版    权:  深圳埃思欧纳信息咨询有限公司版权所有. YYYY-YYYY,  All rights reserved
 * 描    述:  <描述>
 * 修 改 人:  eric.zhang
 * 修改时间:  2009-12-8
 * 跟踪单号:  <跟踪单号>
 * 修改单号:  <修改单号>
 * 修改内容:  <修改内容>
 */
package com.fileUpload.utilities.unpack;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.upload.DiskFile;
import org.apache.struts.upload.FormFile;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;

import com.fileUpload.utilities.UploadUtil;

/**
 * <一句话功能简述> <功能详细描述>
 * 
 * @author eric.zhang
 * @version [版本号, 2009-12-8]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class ExtractZipArchive
{
    private static Log logger = LogFactory.getLog(ExtractZipArchive.class.getName());

    /** 系统临时目录 */
    private static String SYSTMPDIR = System.getProperty("java.io.tmpdir");

    /** 文件大小 */
    private static final int BUFFER = 2048;

    public static List<FormFile> extractArchive(String archive, String destination)
    {
        if (archive == null || destination == null)
        {
            throw new RuntimeException("archive and destination must me set");
        }
        File arch = new File(archive);
        if (!arch.exists())
        {
            throw new RuntimeException("the archive does not exit: " + archive);
        }
        File dest = new File(destination);
        if (!dest.exists() || !dest.isDirectory())
        {
            dest.mkdirs();
            // throw new
            // RuntimeException("the destination must exist and point to a directory: "
            // + destination);
        }
        return extractArchive(arch, dest);
    }

    @SuppressWarnings("deprecation")
    public static List<FormFile> extractArchive(File archive, File destination)
    {
        List<FormFile> fileList = new ArrayList<FormFile>();
        String[] fileTypes = new String[]{"rar", "zip", "doc", "txt", "pdf", "rtf", "ppt", "jpg", "xls", "html", "mht", "htm"};
//        String[] fileTypes = AceonaConfig.getConfig(ConfigKeys.RESUME_TYPE).split(",");
        ZipFile zipFile = null;
        try
        {
            // 暂时支持中文,其它格式的支持需要另外判断
            zipFile = new ZipFile(archive.getAbsolutePath(), "GBK");
        }
        catch (Exception e)
        {
            logger.error(e);
            return fileList;
        }
        if (zipFile != null)
        {
            Enumeration emu = zipFile.getEntries();
            int i = 0;
            while (emu.hasMoreElements())
            {
                try
                {
                    ZipEntry entry = (ZipEntry) emu.nextElement();
                    // 会把目录作为一个file读出一次，所以只建立目录就可以，之下的文件还会被迭代到。
                    if (entry.isDirectory())
                    {
                        new File(destination.getAbsolutePath() + entry.getName()).mkdirs();
                        continue;
                    }
                    // 增加已解压文件列表,如果类型符合简历格式
                    if (UploadUtil.checkTypes(fileTypes, entry.getName().split("\\.")))
                    {
                        BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));
                        File file = new File(destination.getAbsolutePath() + entry.getName());
                        // 加入这个的原因是zipfile读取文件是随机读取的，这就造成可能先读取一个文件
                        // 而这个文件所在的目录还没有出现过，所以要建出目录来。
                        File parent = file.getParentFile();
                        if (parent != null && (!parent.exists()))
                        {
                            parent.mkdirs();
                        }
                        FileOutputStream fos = new FileOutputStream(file);
                        BufferedOutputStream bos = new BufferedOutputStream(fos, BUFFER);

                        int count;
                        byte data[] = new byte[BUFFER];
                        while ((count = bis.read(data, 0, BUFFER)) != -1)
                        {
                            bos.write(data, 0, count);
                        }
                        bos.flush();
                        bos.close();
                        bis.close();

                        if (!(UploadUtil.TYPEZIP.equalsIgnoreCase(UploadUtil.subFileType(file.getName())) || UploadUtil.TYPERAR.equalsIgnoreCase(UploadUtil.subFileType(file.getName()))))
                        {
                            FormFile tempFile = new DiskFile(file.getAbsolutePath());
                            tempFile.setFileSize((int) file.length());
                            tempFile.setFileName(entry.getName());
                            fileList.add(tempFile);
                        }
                    }
                }
                catch (Exception ex)
                {
                    ex.printStackTrace();
                }

            }
            try
            {
                zipFile.close();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
        return fileList;
    }

    public static List<FormFile> extractArchive(FormFile formFile)
    {
        // 通过FormFile获取文件流
        // 1,将文件流存入系统临时根目录2,解压根目录文件,并存入临时目录3,遍历此临时目录,将文件列表路径以list输出
        String tempFormFilePath = SYSTMPDIR + File.separator + formFile.hashCode() + formFile.getFileName();
        String tempFormFileExtractPath = SYSTMPDIR + File.separator + formFile.hashCode();
        boolean fileOk = false;
        try 
        {
            fileOk = UploadUtil.saveFile(formFile.getInputStream(), tempFormFilePath);
            // 存文件进入临时目录成功
            if (fileOk)
            {
                // 开始解压到临时目录
                return extractArchive(tempFormFilePath, tempFormFileExtractPath);
            }
        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args)
    {
        // if (args.length == 2)
        // {
        // extractArchive(args[0], args[1]);
        // }
        // else
        // {
        // System.out.println("usage: java -jar extractArchive.jar <thearchive> <the destination directory>");
        // }
        extractArchive("D:\\workspace10\\test\\rarpack\\JAVA高性能.rar", "D:\\workspace10\\test\\unrarpack\\JAVA高性能");
        // extractArchive("D:\\workspace10\\test\\rarpack\\jsp_tupian (1).rar",
        // "D:\\workspace10\\test\\unrarpack\\jsp_tupian (1)");
        // extractArchive("D:\\workspace10\\test\\rarpack\\JSTL详解.rar",
        // "D:\\workspace10\\test\\unrarpack\\JSTL详解");
        // extractArchive("D:\\workspace10\\test\\rarpack\\SupLogin.rar",
        // "D:\\workspace10\\test\\unrarpack\\SupLogin");
        // extractArchive("D:\\workspace10\\test\\rarpack\\活动照片.rar",
        // "D:\\workspace10\\test\\unrarpack\\活动照片");
    }
}
